<?php

namespace control;

use ReflectionClass;
use ReflectionException;

class printTemplateClass extends adIndexClass
{
    private const page = 'printTemplate';
    private const table = 'print_template';
    private const title = '打印设置';


    /*模板入口页*/
    public function home(): string
    {
        $all    = self::getPowerAll();
        //返回
        $rightHtml = $this->homeRight();
        $html =  componentClass::leftNav([
            'title'=>'模板名称',
            'all'=>$all,
            'click'=>" replaceRightDetail(this) ",
            'allTitle'=>'所有打印设置',
            'rightHtml'=>$rightHtml,
        ]);
        $html      .= <<<EOT
<script>
function replaceRightDetail(obj, cla = '{$this->get('cla')}') {
    let api, menuThree, two, one, id = $(obj).attr('data-id')
    id = id === 'all' ? '' : id
    if (id.length > 0) {
        let that = $(obj).parent('ul')
        menuThree = that.attr('pid');
        two = that.parent('ul').attr('pid');
        one = that.parent('ul').parent('ul').attr('pid');
        ulScal(obj, id)
    }
    $("#container-left li").removeClass('active');
    $(obj).addClass('active')
    api = root + 'control/adIndex.html?cla=' + cla + '&fun=homeRightJson'
    $.post(api, {
        menuOne:one,
        menuTwo: two,
        menuThree: menuThree,
        menuFour: id
    }, function (data) {
        $('#container-detail').html(data.html)
    }, "json");
}
</script>
EOT;
        //返回
        return $this->homeFun($html);
    }

    /*列表页-查询条件*/
    public function homeOptions($isAsync = true)
    {
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    "模板名称" => text(["name" => "name"]),
                    "模板备注" => text(["name" => "text"])
                        . hidden(['name' => 'menuOne', 'value' => $this->post('menuOne')])
                        . hidden(['name' => 'menuTwo', 'value' => $this->post('menuTwo')])
                        . hidden(['name' => 'menuThree', 'value' => $this->post('menuThree')])
                        . hidden(['name' => 'menuFour', 'value' => $this->post('menuFour')]),
                ],
            ],
        ], 1);
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

    public function homeRight(): string
    {
        $html = $this->homeOptions(false);
        //控件
        $button    = "";
        $equal     = [
            'menuOne'   => $this->post('menuOne'),
            'menuTwo'   => $this->post('menuTwo'),
            'menuThree' => $this->post('menuThree'),
            'menuFour'  => $this->post('menuFour'),
        ];
        $equalJson = base64_encode(json_encode($equal, 320));
        if ($this->power(self::page, "edit") && $this->post('menuThree')) {
            $button .= "<span onclick=\"layer('" . $this->get('cla') . "', 'edit', {id:'" . suiji() . "', data: '$equalJson' })\" class='spanButton'>新增</span>\n";
        }
        if ($this->power(self::page, "del")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'operate', {'act': 'del', data: '$equalJson'})\">删除</span>\n";
        }
        if ($this->power(self::page, "state")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get['cla']}', 'operate', {'act': 'changeState', 'state': '启用'})\">启用</span>\n";
        }
        if ($this->power(self::page, "state")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get['cla']}', 'operate', {'act': 'changeState', 'state': '停用'})\">停用</span>\n";
        }
        return $this->search($html, layout: 'pop', toolButton: $button);
    }

    /**
     * 左侧搜索框
     *
     * @return string
     */
    public function getContainerLeftJson(): string
    {
        $json['html'] = self::getPowerAll();
        return json_encode($json, 320);
    }

    /**
     * 获取数据
     *
     * @return array
     */
    private static function receiveData(): array
    {
        global $powerAll;
        $result = [];
        foreach ($powerAll as $one => $oneArray) {
            $oneTemp = [];
            foreach ($oneArray as $two => $twoArray) {
                $twoTemp = [];
                foreach ($twoArray as $three => $threeArray) {
                    $threeTemp = [];
                    foreach ($threeArray as $four => $value) {
                        if (isset($value['print'])) {
                            $threeTemp[$four] = $value['name'];
                        }
                    }
                    if (!empty($threeTemp)) {
                        $twoTemp[$three] = $threeTemp;
                    }
                }
                if (!empty($twoTemp)) {
                    $oneTemp[$two] = $twoTemp;
                }
            }
            if (!empty($oneTemp)) {
                $result[$one] = $oneTemp;
            }
        }
        return $result;
    }

    public static function getPowerAll(array $local = [], string $pid = ''): string
    {
        $result = $local ?: self::receiveData();
        $style  = empty($pid) ? '' : ' class="child-node"';
        $temp   = "<ul $style $pid>";
        // 角标
        $arrow   = arrow;
        $lastone = lastone;
        $textcontent_ico = "<span class='textcontent_ico'></span>";
        foreach ($result as $key => $value) {
            // 判断下级是否存在
            $pid = "pid=$key";
            if (is_array($value)) {
                $temp .= "<li data-id='$key' onclick=\"ulScal(this, '$key')\">$arrow <span class='textcontent'>{$textcontent_ico}{$key}</span></li>";
                $temp .= self::getPowerAll($value, $pid);
            } else {
                $temp .= "<li data-id='$key' onclick=\"replaceRightDetail(this)\">$lastone <span class='textcontent'>{$textcontent_ico}{$value}</span></li>";
            }
        }
        $temp .= '</ul>';
        return $temp;
    }

    /**
     * 异步加载
     */
    public function homeRightJson(): string
    {
        $json['html'] = $this->homeRight();
        return json_encode($json, 320);
    }

    public function homeRightJsonSearch(): string
    {
        return $this->homeSearch();
    }

    /**
     * 四级菜单名称
     *
     * @param $array
     * @return string
     */
    private function menuFourName($array): string
    {
        return empty($this->powerAll[$array['menuOne']][$array['menuTwo']][$array['menuThree']][$array['menuFour']]['name']) ? '' : $this->powerAll[$array['menuOne']][$array['menuTwo']][$array['menuThree']][$array['menuFour']]['name'];
    }

    /**
     * 字段初始化
     */
    public function fieldInit($fun): array
    {
        switch ($fun) {
            default:
                $tr = [
                    'name'      => [
                        'name'  => "模板名称",
                        'width' => 200,
                    ],
                    'menuOne'   => [
                        'name'  => '一级菜单',
                        'width' => 200,
                    ],
                    'menuTwo'   => [
                        'name'  => '二级菜单',
                        'width' => 150,
                    ],
                    'menuThree' => [
                        'name'  => '三级菜单',
                        'width' => 150,
                    ],
                    'menuFour'  => [
                        'name'  => '四级菜单',
                        'width' => 150,
                    ],
                    'list'      => [
                        'name'  => '排序号',
                        'width' => 100,
                        'sort'  => 1,
                    ],
                    'isDefault' => [
                        'name'  => '默认模板',
                        'width' => 100,
                        'sort'  => 1,
                    ],
                    'state'     => [
                        'name'  => '状态',
                        'width' => 100,
                    ],
                ];
        }
        return $tr;
    }

    /*列表页-查询结果*/
    public function homeSearch(): bool|string
    {
        $equal = [
            'menuOne'   => $this->post('menuOne'),
            'menuTwo'   => $this->post('menuTwo'),
            'menuThree' => $this->post('menuThree'),
            'menuFour'  => $this->post('menuFour'),
        ];
        //获取查询结果
        $where = search([
            "like" => [
                "name" => $this->post('name'),//模板名称
            ],
            '='    => $equal,
        ]);
        //排序
        $orderBy = $this->listSort([
            "search" => $this->post('list_sort_key') ?: 'list',
            "sort"   => $this->post('list_sort') ?: "asc",
            "array"  => [],
        ]);
        $page    = $this->page([
            "table" => self::table,
            "where" => $where,
            "order" => $orderBy['orderBy'],
        ]);
        //获取自定义字段参数
        $installSearch = $this->installSearch();
        $body          = [];
        //表格控件区
        $liButton = [
            $this->checkAll("listForm", "id"),
        ];
        //获取记录
        foreach ($page['array'] as $array) {
            //列表控件
            $dominate   = $this->dominate([
                "box"    => ["name" => "id", "value" => $array['id']],
                "detail" => ["title" => "模板详情", "click" => "newIframe('模板详情','" . root . "control/adIndex.html?cla=" . self::page . "&fun=detail&id=" . $array['id'] . "')"],
            ]);
            $liButton[] = $dominate;
            //本行初始化
            $row = [];
            foreach ($installSearch['key'] as $key) {
                switch ($key) {
                    case 'menuFour':
                        $menuFour = $this->menuFourName($array);
                        $row[]    = $menuFour;
                        break;
                    case 'isDefault':
                        $row[] = $array[$key] ? '是' : '否';
                        break;
                    default:
                        $row[] = isset($array[$key]) && $array[$key] ? $array[$key] : '';
                }
            }
            $body[] = $row;
        }
        //控件
        $button = "";
        //生成页面
        $li = $this->li([
            "body"        => $body,
            "install"     => $installSearch,
            "button"      => ["html" => $liButton],
            "orderBySign" => $orderBy,
            "page"        => $page['para'],
        ]);
        //返回
        $json['html'] = $page['hint'] . $button . "<form name='listForm'>" . $li . "</form>" . $page['button'];
        return json_encode($json, 320);
    }

    function getOptionData($menuFour)
    {
        $targetId = $this->post('targetId') ?? '';
        $whereArr = [
            'menuFour' => $menuFour,
            'state'    => '启用',
        ];
        $info     = query(self::table, generateWhere($whereArr));
        if ($targetId) {
            $whereArr['targetId'] = $targetId;
        }
        $result    = find([
            'field' => 'id, name, isDefault, menuOne, menuTwo, menuThree, menuFour',
            'table' => self::table,
            'where' => generateWhere($whereArr) . ' order by list, name ',
        ]);
        $array     = $result['array'] ?? [];
        $equalJson = base64_encode(json_encode([
            'menuOne'   => $info['menuOne'] ?: '',
            'menuTwo'   => $info['menuTwo'] ?: '',
            'menuThree' => $info['menuThree'] ?: '',
            'menuFour'  => $info['menuFour'] ?: $menuFour,
            'model'     => 'design',
            'targetId'  => $targetId,
        ], 320));
        $data      = [];
        $checked   = '';
        foreach ($array as $item) {
            if ($item['isDefault'] == 1) {
                $checked = $item['id'];
            }
            $data[$item['id']] = [
                'id'       => $item['id'],
                'edit'     => 1,
                'name'     => $item['name'],
                'cla'      => 'printTemplate',
                'classify' => 'edit',
                'params'   => "{id: '{$item['id']}', data: '$equalJson'} ",
            ];
        }
        return [$data, $checked, $equalJson];
    }

    function getOption()
    {
        $targetId       = $this->post('targetId') ?: '';
        $menuFour = $this->post('menuFour') ?: '';
        $where = " menuFour = '$menuFour'";
        if ($targetId) {
            $where = " and targetId = '$targetId'";
        }
        $info = query(self::table, $where);
        [$data, $checked] = $this->getOptionData($info['menuFour']);
        return json_encode(['html' => importTemplateClass::radio(['name' => 'tpid', 'value' => $data, 'checked' => $checked], callback: 'layer')], 320);
    }

    /**
     * 选择模板弹窗
     * @return bool|string
     */
    public function selectTemplate(): bool|string
    {
        [$data, $checked, $equalJson] = $this->getOptionData($this->post('cla'));
        $lists  = $this->post('lists') ?: '';
        if(!$lists){
            return json_encode(['warn'=>'请先选择需要打印的数据'],320);
        }
        $html   = $this->layerEdit([
            "table"  => [
                [
                    '选择打印模板：' => "<p><span id='template-option'>" . importTemplateClass::radio(['name' => 'tpid', 'value' => $data, 'checked' => $checked], callback: 'layer') . "</span><button onclick=\"layer('printTemplate', 'edit', {id:'" . static::getId() . "', data: '$equalJson' })\" class='del-row-button button-none'>新增</button></p>",
                ],
            ],
            'hidden' => hidden(['name' => 'lists', 'value' => $lists]) .
                hidden(['name' => 'targetId', 'value' => $this->post('targetId')]) .
                hidden(['name' => 'cla', 'value' => $this->post('cla')]) .
                hidden(['name' => 'fun', 'value' => $this->post('fun')]),
        ]);
        $button = $this->tableShowButton([
            [
                "name"  => '打印预览',
                "type"  => "点击事件",
                "fun"   => empty($lists) ? "msg('暂无可打印的单据')" : "printJump()",
                'style' => 'spanButton span-button-default width100',
            ],
        ]);
        //返回
        return $this->layer([
            "title"  => '打印',
            "height" => 200,
            'width'  => 720,
            "html"   => $html,
            'button' => $button,
            'zindex' => 70,
        ]);
    }

    /**
     * 获取指定key 的上级key 及下级name
     * @param $array
     * @param $searchKey
     * @param $parents
     * @return string|null
     */
    static function findKeyInArray($array, $searchKey, $parents = [])
    {
        foreach ($array as $key => $value) {
            // 当前键是我们要找的键
            if ($key === $searchKey) {
                // 构建返回字符串
                $parentsString = implode(',', $parents); // 将parents数组转换为字符串
                $resultString  = "{$parentsString},{$key},{$value['name']}";
                return $resultString;
            }

            // 如果值是数组，递归搜索
            if (is_array($value)) {
                $result = self::findKeyInArray($value, $searchKey, array_merge($parents, [$key]));
                if ($result) {
                    return $result;
                }
            }
        }
        return null;
    }

    /**
     * 编辑页
     *
     * @return string
     */
    public function edit(): string
    {
        $id     = $this->post('id') ?: '';
        $obj    = $this->post('data') ?: '';
        $result = json_decode(base64_decode($obj), 320);
        //数据查询
        $info = query(self::table, " id = '" . $id . "' ");
        if ($info['id']) {
            $menuOne      = $info['menuOne'] ?: $result['menuOne'];
            $menuTwo      = $info['menuTwo'] ?: $result['menuTwo'];
            $menuThree    = $info['menuThree'] ?: $result['menuThree'];
            $menuFour     = $info['menuFour'] ?: $result['menuFour'];
            $menuFourName = $this->powerAll[$menuOne][$menuTwo][$menuThree][$menuFour]['name'];
        } else {
            [$menuOne, $menuTwo, $menuThree, $menuFour, $menuFourName] = explode(',', self::findKeyInArray($this->powerAll, $result['menuFour']));
        }
        $result['model'] = $result['model']??'';
        $result['targetId'] = $result['targetId']??'';
        $button[] = [
            "name"  => '确认',
            "type"  => "点击事件",
            "cla"   => $this->get('cla'),
            "fun"   => "subForm('" . self::page . "EditForm', root+'control/adIndex.html?cla=" . self::page . "&fun=editEdit&jump=no')",
            'style' => 'width100 li-btn-blue-bg',
        ];
        if ($info['id']) {
            $button[] = [
                "name"  => '删除',
                "type"  => "点击事件",
                "cla"   => $this->get('cla'),
                "fun"   => "layer('printTemplate', 'operate', {id:'$id', act: 'del', 'menuFour': '$menuFour', model:'{$result['model']}', targetId: '{$result['targetId']}'})",
                'style' => 'width100',
            ];
            if($obj) {
                $button[] = [
                    "name"  => '设计',
                    "type"  => "点击事件",
                    "cla"   => $this->get('cla'),
                    "fun"   => "newIframe('打印模板设计', root+'/control/adIndex.html?cla=printTemplate&fun=design&source=layer&id={$info['id']}')",
                    'style' => 'width100',
                ];
            }
        }
        //表单
        $html  = $this->pageEdit([
            "table"  => [
                '基本信息' => [
                    [
                        must . "所属模块：" => $menuOne . ' - ' . $menuTwo . ' - ' . $menuThree . ' - ' . $menuFourName,
                        must . "默认选中：" => radio(['name' => 'isDefault', 'value' => [1 => '是', 0 => '否'], 'checked' => $info['isDefault'] ?: 0]) . componentClass::tipComponent('默认选中表示预先勾选的打印模板', '?'),
                    ],
                    [
                        must . "模板名称：" => text(["name" => "name", "value" => $info['name'],]),
                        must . "排序号："   => text(["name" => "list", "value" => $info['list'],]),
                    ],
                    [
                        "备注：" => textarea(["name" => "text", "value" => $info['text']]),
                    ],
                ],
            ],
            'hidden' => hidden(['name' => 'id', 'value' => $id])
                . hidden(['name' => 'menuOne', 'value' => $menuOne])
                . hidden(['name' => 'menuTwo', 'value' => $menuTwo])
                . hidden(['name' => 'menuThree', 'value' => $menuThree])
                . hidden(['name' => 'menuFour', 'value' => $menuFour])
                . hidden(['name' => 'model', 'value' => $result['model']??''])
                . hidden(['name' => 'targetId', 'value' => $result['targetId']??''])
            ,
        ]);
        $title = $info['id'] ? '编辑模板' : '新增模板';
        //返回
        return $this->layer(["title" => $title, "height" => 250, "html" => $html, 'button' => $this->tableShowButton($button), 'zindex' => 80,]);
    }

    /*模板详情页~基本信息-异步处理*/
    public function editEdit(): bool|string
    {
        $id    = $this->post('id') ?: self::getId();
        $model = $this->post('model') ?: '';
        //赋值
        $field      = [
            "name"      => $this->post('name'),
            "list"      => $this->post('list'),
            "menuOne"   => $this->post('menuOne'),
            "menuTwo"   => $this->post('menuTwo'),
            "menuThree" => $this->post('menuThree'),
            "menuFour"  => $this->post('menuFour'),
            "targetId"  => $this->post('targetId'),
            "isDefault" => $this->post('isDefault'),
            "text"      => $this->post('text'),
        ];
        $annotation = [
            "name"      => '模板名称',
            "list"      => '排序号',
            "menuOne"   => '一级菜单',
            "menuTwo"   => '二级菜单',
            "menuThree" => '三级菜单',
            "menuFour"  => '四级级菜单',
            "isDefault" => '默认选中模板',
            "text"      => '备注',
        ];
        $rules      = [
            "name"      => 'required',
            "list"      => 'required|numeric',
            "isDefault" => 'required|numeric',
            "menuOne"   => 'required',
            "menuTwo"   => 'required',
            "menuThree" => 'required',
            "menuFour"  => 'required',
        ];
        // 校验是否符合规则
        $vt     = new \verify();
        $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
        if ($result === false) {
            $json['warn'] = $vt->getErrs()[0];  // 多个规则提示最前面一条
            goto resp;
        }
        $info = query(self::table, " id = '" . $this->post('id') . "' ");
        //判断
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = "你没有编辑打印模板的权限";
        } elseif (empty($info['id'])) {
            $field['state'] = '启用';
            $field          = array_merge($field, [
                "id"   => $id,
                'stid' => self::$stid,
            ]);
            $json['warn']   = static::insert(["table" => self::table, "field" => $field]);
        } else {
            $json['warn'] = static::update(["table" => self::table, "field" => $field, "where" => "id = '" . $id . "'"]);
        }
        if (in_array($json['warn'], ["新增成功", "更新成功"])) {
            // 如果当前模板设为默认模板，则修改其他模板为非默认
            if ($field['isDefault'] == 1) {
                self::update([
                    "table" => self::table,
                    "field" => ['isDefault' => 0],
                    "where" => generateWhere([
                            "menuOne"   => $field['menuOne'],
                            "menuTwo"   => $field['menuTwo'],
                            "menuThree" => $field['menuThree'],
                            "menuFour"  => $field['menuFour'],
                        ]) . " AND id <> '" . $id . "'",
                ]);
            }
            //添加日志
            $type = mb_substr($json['warn'], 0, 2, 'utf-8');
            $text = $this->control['name'] . $type . "了一个打印模板：" . $field['name'];
            $this->logText(["type" => "role", "text" => $text]);
            if ($model === 'design') {
                if(empty($info['id'])) {
                    $json['script'] = "<script>
                                reloadTemplateOption('$field[menuFour]','$field[targetId]')
                                newIframe('打印模板设计', root + '/control/adIndex.html?cla=printTemplate&fun=design&source=layer&id=$id')
                                </script>";
                }else{
                    $json['script'] = "<script>
                                reloadTemplateOption('$field[menuFour]','$field[targetId]')
                                </script>";
                }
                /*if ($this->get('jump') && $this->get('jump') == 'no') {
                    $json['script'] = "<script>reloadTemplateOption('$field[menuFour]','$field[targetId]')</script>";
                } else {
                    $json['iframeName'] = '打印模板设计';
                    $json['iframe']     = root . '/control/adIndex.html?cla=printTemplate&fun=design&source=layer&id=' . $id;
                }*/
            } else {
                //提示
                $_SESSION['warn'] = $json['warn'];
            }
            $json['warn'] = 2;
        }
        //返回
        resp:
        return json_encode($json, 320);
    }

    /*模板管理-模板详情页*/
    public function detail(): string
    {
        $info = query(self::table, " id = '" . $this->get('id') . "' ");
        if (!$this->power(self::page, "see")) {
            $html = "你没有模板查看权限";
        } elseif (empty($this->get('id'))) {
            $html = "模板ID为空";
        } elseif (empty($info['id'])) {
            $html = "未找到此模板";
        } else {
            $data = [
                "id"    => $info['id'],
                "title" => $info['name'],
            ];
            //按钮
            $button = [];
            if ($this->power(self::page, "edit")) {
                $button[] = [
                    "name"  => "编辑",
                    "type"  => "弹出层",
                    "cla"   => $this->get('cla'),
                    "fun"   => "edit",
                    "post"  => ["id" => $info['id']],
                    'style' => 'li-btn-blue-bg',
                ];
                $button[] = [
                    "name" => "复制",
                    "type" => "弹出层",
                    "cla"  => $this->get('cla'),
                    "fun"  => "copy",
                    "post" => ["id" => $info['id']],
                ];
                $button[] = [
                    "name" => "预览",
                    "type" => "外部链接",
                    'url'  => root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=preview&id=' . $info['id'],
                ];
                $button[] = [
                    "name" => "设计",
                    "type" => "外部链接",
                    'url'  => root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=design&id=' . $info['id'],
                ];
            }
            $modelName = $info['menuOne'] . ' - ' . $info['menuTwo'] . ' - ' . $info['menuThree'] . ' - ' . $this->powerAll[$info['menuOne']][$info['menuTwo']][$info['menuThree']][$info['menuFour']]['name'];
            //生成表单
            $data['button'] = $this->tableShowButton($button);
            $data['html']   = $this->tableShow([
                "模板档案" => [
                    [
                        "模板名称" => $info['name'],
                        '所属模块' => $modelName,
                        "排序号"   => $info['list'],
                        "模板ID"   => $info['id'],
                    ],
                    [
                        "更新时间" => $info['updateTime'],
                        "创建时间" => $info['time'],
                        "默认模板" => $info['isDefault'] ? '是' : '否',
                    ],
                    [
                        "备注" => pre($info['text']),
                    ],
                ],
            ]);
            //生成页面
            $html = $this->tab($data);
        }
        //返回
        return $html;
    }

    /**
     * 复制模板
     *
     * @return string
     */
    public function copy()
    {
        $info = query(self::table, " id = '" . $this->post('id') . "' ");
        //判断
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = "你没有编辑打印模板的权限";
        } elseif (empty($info['id'])) {
            $json['warn'] = "参数错误";
        } else {
            unset($info['id'], $info['time'], $info['updateTime']);
            $field        = array_merge($info, [
                "id"        => self::getId(),
                "state"     => '启用',
                'stid'      => self::$stid,
                'isDefault' => 0,
            ]);
            $json['warn'] = static::insert(["table" => self::table, "field" => $field]);
        }
        if (in_array($json['warn'], ["新增成功", "更新成功"])) {
            //添加日志
            $type = mb_substr($json['warn'], 0, 2, 'utf-8');
            $text = $this->control['name'] . $type . "了一个打印模板：" . $info['name'];
            $this->logText(["type" => "role", "text" => $text]);
            //提示
            $_SESSION['warn'] = $json['warn'];
            $json['warn']     = 2;
        }
        //返回
        resp:
        return json_encode($json, 320);
    }

    /**
     * 更新模板
     *
     * @return string
     */
    public function upbody(): string
    {
        $id = $this->post('id') ?: self::getId();
        //赋值
        $field      = [
            "tplBody" => $this->post('tplBody'),
        ];
        $annotation = [
            "tplBody" => '模板内容',
        ];
        $rules      = [
            "tplBody" => 'required',
        ];
        // 校验是否符合规则
        $vt     = new \verify();
        $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
        if ($result === false) {
            $json['warn'] = $vt->getErrs()[0];  // 多个规则提示最前面一条
            goto resp;
        }
        $info = query(self::table, " id = '" . $this->post('id') . "' ");
        //判断
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = "你没有编辑打印模板的权限";
        } else {
            $json['warn'] = static::update(["table" => self::table, "field" => $field, "where" => "id = '" . $id . "'"]);
        }
        if (in_array($json['warn'], ["新增成功", "更新成功"])) {
            //添加日志
            $type = mb_substr($json['warn'], 0, 2, 'utf-8');
            $text = $this->control['name'] . $type . "了一个打印模板：" . $info['name'];
            $this->logText(["type" => "role", "text" => $text]);
            //提示
            $_SESSION['warn'] = $json['warn'];
            $json['warn']     = 2;
        }

        //返回
        resp:
        return json_encode($json, 320);
    }

    // 操作中转
    public function operate(): bool|string
    {
        $act    = $this->post('act') ?? '';
        $pwd    = false; // 需要密码
        $form   = $power = '';
        $append = [];
        switch ($act) {
            case 'changeState':
                $act      = 'state';
                $msg      = self::title . '修改状态';
                $title    = self::page . 'Change';
                $function = 'changeState';
                $form     = self::page . 'OperateForm, listForm';
                if ($this->post('state')) {
                    $append = [
                        0 => hidden(['name' => 'state', 'value' => $this->post('state')]),
                    ];
                }
                $power = '';
                break;
            default:
                $act      = 'del';
                $msg      = '删除' . self::title;
                $title    = self::page . 'Delete';
                $function = 'delete';
                $form     = self::page . 'OperateForm, listForm';
                $append   = [
                    0 => hidden(['name' => 'model', 'value' => $this->post('model') ?? '']),
                    1 => hidden(['name' => 'targetId', 'value' => $this->post('targetId') ?? '']),
                ];
                $power    = '';
                break;
        }
        if (!$this->power(self::page, $act)) {
            $_SESSION['warn'] = '你还没有' . $msg . '的权限';
            $json             = [
                'warn' => 2,
                'href' => root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=home',
            ];
        } else {
            return $this->confirm([
                'title'    => $title,
                'function' => $function,
                'form'     => $form,
                'power'    => $power,
                'pwd'      => $pwd,
                'append'   => $append,
            ]);
        }

        resp:
        return json_encode($json, 320);
    }

    /**
     * 删除
     *
     * @return bool|string
     */
    public function delete(): bool|string
    {
        $model    = $this->post('model') ?: '';
        $targetId = $this->post('targetId') ?: '';
        $array    = $model ? $this->post('id') : ($this->post('listId') ?? $this->post('id'));
        if (!$this->power(self::page, "del")) {
            $json['warn'] = "你没有删除的权限";
        } elseif (empty($array)) {
            $json['warn'] = "你一个数据都没有选择呢";
        } else {
            $text  = "";
            $x     = 0;
            $array = is_array($array) ? $array : [$array];
            foreach ($array as $id) {
                $info = query(self::table, " id = '$id' ");
                if ($info['isDefault'] == 1) {
                    $text = "删除失败，默认模板无法删除";
                } else {
                    //最后删除基本参数
                    delete(["table" => self::table, "where" => " id = '$id' "]);
                    //返回
                    $text = "删除成功";
                    $x++;
                }
                $text .= "，ID【" . $info['id'] . "】, 模板名称【{$info['name']}】" . $text . "。<br>";
            }
            //添加日志
            $text = $this->control['name'] . "删除了" . $x . "个" . self::title . "，结果如下：<br>" . $text;
            $this->logText(["type" => self::page, "text" => $text]);
            $msg = "删除了" . $x . "个" . self::title . "，详情见系统日志。";
            if ($model != 'design') {
                $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home";
                $_SESSION['warn'] = $msg;
            } else {
                $json['script'] = "<script>reloadTemplateOption('$info[menuFour]', '$targetId');msg('$msg')</script>";
            }
            $json['warn'] = 2;
        }
        return json_encode($json, 320);
    }


    /**
     * 修改状态
     *
     * @return bool|string
     */
    public function changeState(): bool|string
    {
        $array = $this->post('listId') ?? $this->post('id');
        $state = $this->post('state') ?: '停用';
        $act   = 'state';
        $json  = [];
        if (!$this->power(self::page, $act)) {
            $json['warn'] = "你没有此权限的权限";
        } elseif (empty($array)) {
            $json['warn'] = "你一条记录都没有选择呢";
        } else {
            $text  = '';
            $x     = 0;
            $array = is_array($array) ? $array : [$array];
            // 修改field
            $fieldKey = 'state';
            foreach ($array as $id) {
                $where = " id = '$id' ";
                $info  = query(self::table, $where);
                if (static::isNull($info['id'])) {
                    continue;
                }
                $fieldVlaue = ($state === '停用') ? '停用' : '启用';
                // 修改状态
                static::update([
                    "table" => self::table,
                    'field' => [
                        $fieldKey => $fieldVlaue,
                    ],
                    "where" => $where,
                ]);
                //添加记录
                $text .= "管理员{$this->control['name']}修改了一条" . self::title . "：ID【{$id}】<br>";
                $x++;
            }
            // 写入日志
            $this->logText(["type" => self::page, "text" => $text]);
            $_SESSION['warn'] = "修改了{$x}条" . self::title;
            $json['warn']     = 2;
            $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home";
        }
        resp:
        return json_encode($json, 320);
    }

    /**
     * 获取字段类型
     *
     * @param $type
     * @return string
     */
    private static function getFieldType($type): string
    {
        if (str_contains($type, 'text')) {
            return 'longText';
        } elseif (str_contains($type, 'url') || str_contains($type, 'src')) {
            return 'image';
        } else {
            return 'text';
        }
    }

    /**
     * 显示字段
     *
     * @param $sql
     * @return array
     * @throws \Exception
     */
    private static function showFiled($sql): array
    {
        $result = sqlFind($sql);
        $items  = [];
        foreach ($result as $value) {
            $items[] = [
                'title' => $value['Comment'],
                'field' => $value['Field'],
                'type'  => self::getFieldType($value['Type']),
            ];
        }
        return $items;
    }

    /**
     * 获取表名
     *
     * @string cla 类名
     * @param string $cla
     * @return array
     * @throws ReflectionException
     */
    private static function getTable(string $cla): array
    {
        $tables = [];
        $array  = ['table', 'tableMx'];
        $cla    = !str_contains($cla, '\\') ? '\\control\\' . $cla : $cla;
        foreach ($array as $item) {
            $table = (new ReflectionClass($cla))->getConstant($item);
            if ($table !== false) {
                $tables[$item] = $table;
            }
        }
        return $tables;
    }


    /**
     * 设计模式
     *
     * @return string
     * @throws \Exception
     */
    public function design(): string
    {
        $id   = $this->get('id');
        $info = query(self::table, " id = '$id' ");
        if (empty($info['id'])) {
            exit('参数错误');
        }
        $cla = $info['menuFour'] . 'Class';
        try {
            $tables = self::getTable($cla);
        } catch (ReflectionException) {
            $tables = [];
        }
        $json  = 'new hiprint.PrintElementTypeGroup("字段", [' . PHP_EOL;
        $basic = $detail = '';
        foreach ($tables as $item) {
            $array = self::showFiled('SHOW FULL fields FROM ' . $item);
            if (!str_contains($item, 'detail')) {
                $basicTemp = '';
                foreach ($array as $v) {
                    if ($v['title']) {
                        $v['text']  = $v['title'];
                        $v['title'] = '标题：' . $v['title'] . '， 字段名：' . $v['field'];
                        $v['tid']   = 'leftModule.' . ($v['field'] === 'text' ? $v['field'] . 's' : $v['field']);
                        unset($v['field'],);
                        $basicTemp .= json_encode($v, 320) . ",\n";
                    }
                }
                $basic .= rtrim($basicTemp, ',');
            } else {
                $detailTemp = '';
                foreach ($array as $value) {
                    if ($value['title']) {
                        $value['printElementType'] = [
                            'title' => '表格',
                            'type'  => 'tableCustom',
                        ];
                        $arr                       = array_merge($value, [
                            'align'   => 'center',
                            'width'   => 100,
                            'checked' => true,
                            'data'    => $value['title'],
                        ]);
                        $detailTemp                .= json_encode($arr, 320) . ",\n";
                    }
                }
                if ($detailTemp) {
                    $detail .= <<<EOT
{
	tid: 'leftModule.detail',
	title: '详情表',
	type: 'table',
	editable: true,
	columnDisplayEditable: true,	//列显示是否能编辑
	columnDisplayIndexEditable: true, //列顺序显示是否能编辑
	columnTitleEditable: true, //列标题是否能编辑
	columnResizable: true, //列宽是否能调整
	columnAlignEditable: true, //列对齐是否调整
	columns: [
		[$detailTemp]
	]
}
EOT;
                }
            }
        }
        $json      .= $basic . $detail . ']),';
        $printData = null;

        // 返回数据
        $params = [
            'root'      => root,
            'title'     => $info['name'],
            'id'        => $info['id'],
            'source'    => $this->get('source') ?: '',
            'sourceId'  => $this->get('sourceId') ?: '',
            'targetId'  => $info['targetId'],
            'printJson' => $info['tplBody'] ? self::htmlDecode($info['tplBody']) : '{}',
            'printData' => $printData ?: '{}',
            'json'      => $json,
            'warn'      => warn(),
        ];
        return template($params, 'design.html');
    }


    /** 视图函数
     *
     * @param string $template
     * @param array $data
     * @return string
     */
    private static function view(string $template, array $data): string
    {
        // 打印模板
        $printJson = self::htmlDecode($template);
        // 打印数据
        if (!empty($data)) {
            // 解决数据精度问题，去除多余的0
            $data = self::formateNumberArray($data);
            if (!empty($data['detail'])) {
                $result = [];
                foreach ($data['detail'] as $key => $value) {
                    $result[$key] = self::formateNumberArray($value);
                }
                $data['detail'] = $result;
            }
            $printData = json_encode($data, 320);
        } else {
            $printData = '{}';
        }

        $params = [
            'root'      => root,
            'printJson' => $printJson ?: '{}',
            'printData' => $printData ?: '{}',
        ];
        return template($params, 'preview.html');
    }

    /**
     * 运行
     *
     * @param string $page
     * @param array $data
     * @param string $name
     * @return string
     */
    public function start(string $page, array $data, string $name = ''): string
    {
        $tplBody = $this->getTemplateBody($page, $data, $name);

        if (empty($tplBody) || empty($data)) {
            return '模板或数据不存在';
        }
        return self::view($tplBody, $data);
    }

    private function getTargetId(string $page, array $data): ?string
    {
        $targetKey = match ($page) {
            'saleSendOrder', 'saleRefundOrder', 'saleOrder', 'quotations'                => 'khid',
            'purchaseGetOrder,purchaseRefundOrder,purchaseOrder,purchaseEstimationOrder' => 'supplierId',
            default                                                                      => '',
        };
        if (isset($data[$targetKey])) {
            return $data[$targetKey];
        } elseif (isset(reset($data)[$targetKey])) {
            return reset($data)[$targetKey];
        }
        return null;
    }

    public function getTemplateBody(string $page, array $data, string $name = ''): string|null
    {
        $tpid = $this->get('tpid') ?: '';
        if (!self::isNull($tpid)) {
            return query(self::table, " id = '$tpid' ")['tplBody'];
        }

        // 获取targetId
        $targetId = $this->getTargetId($page, $data);
        $and      = '';

        if ($targetId) {
            $and .= " and targetId = '$targetId' ";
        } else {
            if ($name) {
                $and .= " and name = '$name' ";
            }
        }

        $baseWhere = " menuFour = '$page' AND state = '启用' ";
        // 查询供应商或者客户模板
        $tpl = query(self::table, $baseWhere . $and);
        if (empty($tpl['tplBody'])) {
            // 查询默认模板
            $where = $baseWhere . " and isDefault = 1 ";
            return query(self::table, $where)['tplBody'];
        }

        $baseWhere .= $and;
        $where     = $baseWhere . " and isDefault = 1 ";
        $tpl       = query(self::table, $where);
        // 默认模板不存在
        if (empty($tpl['tplBody'])) {
            return query(self::table, $baseWhere)['tplBody'];
        }
        return $tpl['tplBody'];
    }


    /**
     * 模板查看
     *
     * @return string
     */
    public function preview(): string
    {
        $id  = $this->get('id');
        $tpl = query(self::table, " id = '$id' AND state = '启用' ");
        if (empty($tpl['tplBody'])) {
            return '模板或数据不存在';
        }
        return $this->view($tpl['tplBody'], []);
    }
}
